#include "service_bus_v2.h"
#include <iostream>
#include <chrono>

namespace cpp_backend {
namespace framework {

ServiceBusV2::ServiceBusV2()
    : load_balance_strategy_(LoadBalancer::Strategy::RoundRobin)
    , running_(false)
    , initialized_(false) {
}

ServiceBusV2::~ServiceBusV2() {
    Shutdown();
}

void ServiceBusV2::Initialize(database::RedisPool* redis_pool) {
    if (initialized_.load()) {
        std::cout << "ServiceBusV2 already initialized" << std::endl;
        return;
    }
    
    std::cout << "[ServiceBusV2] Initializing..." << std::endl;
    
    // 创建核心组件
    registry_ = std::make_unique<ServiceRegistry>(redis_pool);
    load_balancer_ = std::make_unique<LoadBalancer>();
    grpc_client_pool_ = std::make_unique<GrpcClientPool>();
    
    // 启动健康检查线程
    running_ = true;
    start_health_check_thread();
    
    initialized_ = true;
    
    std::cout << "[ServiceBusV2] Initialized successfully" << std::endl;
}

void ServiceBusV2::Shutdown() {
    if (!running_.load()) {
        return;
    }
    
    std::cout << "[ServiceBusV2] Shutting down..." << std::endl;
    
    running_ = false;
    
    // 等待健康检查线程退出
    if (health_check_thread_.joinable()) {
        health_check_thread_.join();
    }
    
    // 清理资源
    grpc_client_pool_->clear();
    
    initialized_ = false;
    
    std::cout << "[ServiceBusV2] Shutdown complete" << std::endl;
}

Response ServiceBusV2::CallService(
    const std::string& service_name,
    const Request& request
) {
    if (!initialized_.load()) {
        return Response::Error(
            ErrorCode::INTERNAL_ERROR,
            "ServiceBusV2 not initialized"
        );
    }
    
    try {
        // 1. 服务发现
        auto instances = discover_service(service_name);
        if (instances.empty()) {
            return Response::Error(
                ErrorCode::SERVICE_NOT_FOUND,
                "Service not found: " + service_name
            );
        }
        
        // 2. 负载均衡选择实例
        auto instance = select_instance(instances, request.GetRequestId());
        
        // 3. gRPC调用
        return rpc_call(instance, request);
        
    } catch (const std::exception& e) {
        return Response::Error(
            ErrorCode::INTERNAL_ERROR,
            "RPC call failed: " + std::string(e.what())
        );
    }
}

void ServiceBusV2::CallServiceAsync(
    const std::string& service_name,
    const Request& request,
    std::function<void(const Response&)> callback
) {
    // 在独立线程中执行
    std::thread([this, service_name, request, callback]() {
        auto response = CallService(service_name, request);
        if (callback) {
            callback(response);
        }
    }).detach();
}

std::vector<ServiceInstance> ServiceBusV2::discover_service(
    const std::string& service_name
) {
    return registry_->discover(service_name);
}

ServiceInstance ServiceBusV2::select_instance(
    const std::vector<ServiceInstance>& instances,
    const std::string& key
) {
    return load_balancer_->select(instances, load_balance_strategy_, key);
}

Response ServiceBusV2::rpc_call(
    const ServiceInstance& instance,
    const Request& request
) {
    // 1. 从连接池获取客户端
    auto client = grpc_client_pool_->get_client(instance.host, instance.port);
    
    // 2. 调用RPC
    auto response = client->call(request);
    
    // 3. 归还客户端到池
    grpc_client_pool_->return_client(client);
    
    return response;
}

void ServiceBusV2::start_health_check_thread() {
    health_check_thread_ = std::thread([this]() {
        health_check_loop();
    });
}

void ServiceBusV2::health_check_loop() {
    std::cout << "[ServiceBusV2] Health check thread started" << std::endl;
    
    while (running_.load()) {
        try {
            // 执行健康检查
            registry_->health_check();
            
        } catch (const std::exception& e) {
            std::cerr << "[ServiceBusV2] Health check error: " << e.what() << std::endl;
        }
        
        // 每10秒检查一次
        std::this_thread::sleep_for(std::chrono::seconds(10));
    }
    
    std::cout << "[ServiceBusV2] Health check thread stopped" << std::endl;
}

} // namespace framework
} // namespace cpp_backend
